<?php

namespace Biz\service\admin\tools;

use App\Pockets\GridDataModel;
use Doraemon\pockets\constInterface\LinkConf;
use Doraemon\tools\HhzEnv;
use Doraemon\tools\Msg2Admin;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Form;
use Encore\Admin\Widgets\Tab;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\MessageBag;
use function Clue\StreamFilter\fun;

abstract class SimplePageTpl implements InterfaceListTpl
{
    const TPL_CONFIG_TPL_NAME = '列表';
    private int $pageSize = 20;
    private int $page = 1;
    private int $offset = 0;
    private bool $isCreate = false;
    private array $requestCondition = [];
    private $formInfo;
    private $formInfoId = 0;
    private int $pid = 0;
    private Request $request;
    protected bool $disableLimitCondition = false;

    public function genExportButton(Grid\Tools  $tool)
    {
        $exportUri = static::getRoute()->getExportRoute(0, ['_export' => json_encode($this->getRequestCondition())]);
        $tool->prepend($this->userButton(admin_url($exportUri), 'fa-download', '导出'));
    }

    public function setExportRequestCondition()
    {
        $export = $this->getRequest()->input('_export', []);
        if ($export) $export = json_decode($export, true);
        $this->setRequestCondition($export);
    }
    public function getExportList(): array
    {
        $this->setExportRequestCondition();
        $this->disableLimitCondition = true;
        return $this->getList();
    }

    public function getLimitCondition(): array
    {
        return $this->disableLimitCondition ? [] : ['LIMIT' => [$this->getOffset(), $this->getPageSize()]];
    }
    /**
     * @param array $requestCondition
     */
    public function setRequestCondition(array $requestCondition): void
    {
        $this->requestCondition = $requestCondition;
    }

    /**
     * @return int
     */
    public function getPid(): int
    {
        return $this->pid;
    }

    /**
     * @param int $pid
     */
    public function setPid(int $pid): void
    {
        $this->pid = $pid;
    }

    abstract static function getRoute(): SimpleRouteTpl;


    /**
     * ['text' => '', 'url' => '']
    */
    public function breadcrumb(): array
    {
        return [];
    }

    /**
     * ['title' => '', 'message' => '']
     */
    public function withInfoHtml(): array
    {
        return [];
    }

    public function clearInfoHtml()
    {
        session()->flash('info', false);
    }

    public function description(): string
    {
        return '';
    }


    public function tab(): ?\Encore\Admin\Widgets\Tab
    {
        return null;
    }

    public function condition(): array
    {
        return [];
    }

    public function setFormInfo($formInfo)
    {
        $this->formInfo = $formInfo;
    }

    public function setFormInfoId($id)
    {
        if ($id) $this->formInfoId = $id;
    }

    public function getFormInfoId()
    {
        return $this->formInfoId;
    }

    public function formInfo()
    {
        return $this->formInfo;
    }

    public function isCreate(): bool
    {
        return $this->isCreate;
    }

    public function setIsCreate($flag = true)
    {
        $this->isCreate = $flag;
    }

    public function sortApi()
    {
        $sort = $this->request->input('sort');
        if (!empty($sort)) {
            $this->sort($sort);
        }
    }

    public function deleteApi($id): \Illuminate\Http\JsonResponse
    {
        $status = true;
        $message = "删除成功";
        try {
            $this->delete($id);
        } catch (\Exception $e) {
            $status = false;
            $message = "操作失败,信息:" . $e->getMessage();
        }

        return response()->json(compact('status', 'message'));
    }

    public function saveApi(SimpleRouteTpl $route)
    {
        try {
            $all = $this->request->all();
            $id = $all['id'] ?? 0;
            $this->save($all);
            $success = new MessageBag([
                'title' => ($id > 0 ? '编辑' : '添加') . '成功'
            ]);
            return redirect(admin_url($route->getListRoute($this->getPid())))->with(compact('success'));
        } catch (Exception $e) {
            $error = new MessageBag([
                'title' => '操作失败,信息:' . $e->getMessage() . ' line:' . $e->getLine()
            ]);
            return back()->withInput()->with(compact('error'));
        }
    }

    public function exportDisplay()
    {
        
    }

    public function createDisplay(Content $content, $id, SimpleRouteTpl $route): Content
    {
        $info = $id ? $this->getFormInfo($id) : $this->getDefaultFormInfo();
        $this->setFormInfo($info);
        $this->setFormInfoId($id);
//        if ($id == 0) $this->setIsCreate();
        $form = new Form($info);
        $form->action(admin_url($route->getSaveRoute($this->getPid())));
        $form->hidden('id');
        $this->getForm($form);
        $header = ($id > 0 ? '编辑' : '添加') . $this->getTitle();
        $breadcrumb = array_merge($this->breadcrumb(), [
            ['text' => $this->getListTitle(), 'url' => admin_url($route->getListRoute($this->getPid()))],
            ['text' => $header]
        ]);
        $content->breadcrumb(...$breadcrumb);
        $content->description($this->description() ?: ' ');

        $tab = new Tab();
        $tab->add('表单信息', $form);
        return $content
            ->header($header)
            ->row($tab)
            ;
    }

    public function listDisplay(Content $content): Content
    {
        $this->requestCondition = $this->condition();
        $gridModel = new GridDataModel($this->getList(), $this->getTotal(), ['perPage' => $this->getPageSize()]);
        $grid = Admin::grid($gridModel, function (Grid $grid) use ($gridModel) {
            $grid->paginate($gridModel->getPerPage());
            $grid->disableExport();
            $grid->disableRowSelector();
            $this->getGrid($grid);
        });
        if ($breadcrumb = $this->breadcrumb()) {
            $breadcrumb[] = ['text' => $this->getListTitle()];
            $content->breadcrumb(...$breadcrumb);
        }

        if ($withInfo = $this->withInfoHtml()) {
            $content->withInfo(...$withInfo);
        } else {
            $this->clearInfoHtml();
        }
        $content = $content->header($this->getListTitle());
        if ($tab = $this->tab()) {
            $content->row($tab);
        }
        $content->row($grid);
        return $content;
    }

    public function init(Request $request, $pid = 0): SimplePageTpl
    {
        $this->setRequest($request);
        $this->setPage($page = max($request->input('page', 1), 1));
        $this->setPageSize($pageSize = $request->input('per_page', $this->getPageSize()));
        $this->setOffset(($page - 1) * $pageSize);
        $this->setPid($pid);
        return $this;
    }

    public function isOnline(): bool
    {
        return HhzEnv::isProduction();
    }

    public function email($username)
    {
        $arr = $username;
        if (is_scalar($arr)) $arr = [$username];
        $arr = array_unique($arr);
        $arr = array_filter($arr);
        $response = array_map(function ($v) {
            return $v . '@haohaozhu.com';
        }, $arr);
        return is_array($username) ? array_values($response) : current($response);
    }

    public static function uniqueFilter(array $arr): array
    {
        return array_values(array_unique($arr));
    }

    public static function multiFormInputFilter(array $arr): array
    {
        return array_values(array_unique(array_filter($arr)));
    }

    public function isAdmin()
    {
        return Admin::user()->isAdministrator();
    }

    public function adminId()
    {
        return Admin::user()->id;
    }

    /**
     * @return array
     */
    public function getRequestCondition(): array
    {
        return $this->requestCondition;
    }

    /**
     * @return int
     */
    public function getOffset(): int
    {
        return $this->offset;
    }

    /**
     * @param int $offset
     */
    public function setOffset(int $offset): void
    {
        $this->offset = $offset;
    }

    /**
     * @return Request
     */
    public function getRequest(): Request
    {
        return $this->request;
    }

    /**
     * @param Request $request
     * @return SimplePageTpl
     */
    public function setRequest(Request $request): SimplePageTpl
    {
        $this->request = $request;
        return $this;
    }

    /**
     * @return int
     */
    public function getPage(): int
    {
        return $this->page;
    }

    /**
     * @param int $page
     */
    public function setPage(int $page): void
    {
        $this->page = $page;
    }

    /**
     * @return string
     */
    public static function getListTitle(): string
    {
        return static::TPL_CONFIG_TPL_NAME . "管理";
    }

    /**
     * @return string
     */
    public static function getTitle(): string
    {
        return static::TPL_CONFIG_TPL_NAME;
    }

    /**
     * @return int
     */
    public function getPageSize(): int
    {
        return $this->pageSize;
    }

    /**
     * @param int $pageSize
     */
    public function setPageSize(int $pageSize): void
    {
        $this->pageSize = $pageSize;
    }


    /**
     * @param string $title
     * @param string $message
     * @param string $icon warning | danger | info
     * @return string
     */
    public static function html(string $title = '提示', string $message = '', string $icon = 'info'): string
    {
        return <<<MSG
<div class="alert alert-$icon alert-dismissable">
    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
    <h4><i class="icon fa fa-warning"></i>$title</h4>
    <p>$message</p>
</div>
MSG;
    }

    /**
     * @param string $link
     * @param string $addContent
     * @param string $title
     * @param string $icon warning | danger | info
     * @return string
     */
    public static function redirect(string $link = '', string $addContent = '', string $title = '提示', string $icon = 'warning'): string
    {
        if (empty($link)) return '';
        $message = $addContent . "该功能已经迁移至<a style='color: blue' target='_blank' href='$link'>这里</a>";
        return <<<MSG
<div class="alert alert-$icon alert-dismissable">
    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
    <h5><i class="icon fa fa-warning"></i>$title</h5>
    <br/>
    <p>$message</p>
</div>
MSG;
    }

    public static function simpleMethod($function, $pjax = false, $message = "操作成功"): \Illuminate\Http\JsonResponse
    {
        try {
            $status = true;

            call_user_func_array($function, []);

        } catch (\Exception $e) {
            $status = false;
            $message = $e->getMessage();
            if (!$pjax) {
                return response()->json(['errors' => [$message]], 422);
            }
        }
        return response()->json(compact('status', 'message'));
    }

    public function putApi($id): \Illuminate\Http\JsonResponse
    {
        return Msg2Admin::simpleMethod(function () use ($id) {
            $all = $this->request->all();
            $this->put($all, $id);
        });
    }

    public function linkOptions(): array
    {
        $response = [];
        foreach (LinkConf::LINK_CONF as $group) {
            foreach ($group['group_list'] as $option) {
                $name = $option['name'];
                $link_type = $option['link_type'];
                $deprecated = (int) $option['deprecated'] ?? 0;
                if ($deprecated > 0) continue;
                $response[$link_type] = $name;
            }
        }
        return $response;
    }

    protected function getDefaultFormInfo(): array
    {
        return [];
    }
}